/****************************************************************************

Force Engine v0.5

Creado: 28/03/08
Clase: Mesh.cpp
Hecho by: German Battiston AKA Melkor

Modificado: 18/08/08

Modificado: 29/03/09
Modificacion by: Maximiliano Carrion AKA Riagan

****************************************************************************/

//---------------------------------------------------------------------------
#include "Mesh.h"
#include "../Graphics/Graphics.h"
#include "../Graphics/GraphicsStructs.h"
#include "../X Importer/XMeshImporter.h"
//---------------------------------------------------------------------------
Mesh::Mesh(Graphics &rkGraphics)
:
Entity3D(rkGraphics),
uiVtxCount(0),
uiIdxCount(0),
m_pIndexBuffer(NULL),
m_pVertexBuffer(NULL),
m_pkDevice(NULL),
m_pkMaterial(NULL)
{
	m_pkImporter = new XMeshImporter(rkGraphics);

	m_pIndexBuffer = new IndexBuffer();
	m_pVertexBuffer = new VertexBuffer<MeshVertex,D3DFVF_MESHVERTEX>;

	m_pkDevice = rkGraphics.GetDevice();

	m_pkBoundingVolume = new BVH(rkGraphics);
}
//---------------------------------------------------------------------------
Mesh::~Mesh()
{
	m_pIndexBuffer->Release();
	delete m_pIndexBuffer;
	m_pIndexBuffer = NULL;

	m_pVertexBuffer->Release();
	delete m_pVertexBuffer;
	m_pVertexBuffer = NULL;

	delete m_pkImporter;
	m_pkImporter = NULL;

	delete m_pkBoundingVolume;
	m_pkBoundingVolume = NULL;

	DeInitialize();
}
//---------------------------------------------------------------------------
void Mesh::Draw()
{
	if(m_pkMaterial->m_kTexture)
	{
		m_pkGraphics->BindTexture(*(m_pkMaterial->m_kTexture));
	}

	m_pkGraphics->BindMaterial(*m_pkMaterial);
	/*for(DWORD i = 0; i < numMaterials; i++)
	{
		m_pkGraphics->BindMaterial(m_pkMaterial[i]);
	}*/
	
	m_pkGraphics->LoadIdentity();
	SetTransform();

	m_pkGraphics->Draw<MeshVertex,D3DFVF_MESHVERTEX>( *m_pVertexBuffer,
												      *m_pIndexBuffer,
												      D3DPT_TRIANGLELIST );
	//m_pkBoundingVolume->Draw(rkGraphics);
	if(m_pkMaterial->m_kTexture)
	{
		m_pkGraphics->UnbindTexture(); // si descomento esto los meshes se ven sin textura, no deberia pasar
	}	
}
//---------------------------------------------------------------------------
bool Mesh::LoadMesh(std::string szFileName)
{
	if(!m_pkImporter->LoadMeshFromX(szFileName, *this, m_pkDevice))
	{
		return false;
	}

	return true;
}
//---------------------------------------------------------------------------
bool Mesh::Initialize()
{
	if(!m_pkGraphics->GetIndexBuffer(m_pIndexBuffer,m_kIndexCollection,uiIdxCount))
	{
		return false;
	}

	if(!m_pkGraphics->GetVertexBuffer(m_pVertexBuffer,m_kVertexCollection,uiVtxCount))
	{
		return false;
	}
	
	m_pkBoundingVolume->TraceBVH(m_kVertexCollection, uiVtxCount);

	return true;
}
//---------------------------------------------------------------------------
void Mesh::DeInitialize()
{
	uiVtxCount = 0;
	uiIdxCount = 0;
}
//---------------------------------------------------------------------------
void Mesh::SetIndices(short * pkIndexCollection)
{
	m_kIndexCollection = new short[uiIdxCount];

	for(int i = 0; i < uiIdxCount; i++)
	{
		m_kIndexCollection[i] = pkIndexCollection[i];
	}
}
//---------------------------------------------------------------------------
void Mesh::SetVertices(MeshVertex * pkVertexCollection)
{
	m_kVertexCollection = new MeshVertex[uiVtxCount];

	for(int i = 0; i < uiVtxCount; i++)
	{
		m_kVertexCollection[i] = pkVertexCollection[i];
	}

	m_pkBoundingVolume->TraceBVH(m_kVertexCollection, uiVtxCount);
}
//---------------------------------------------------------------------------
void Mesh::SetMaterial(Material * pkMaterial)
{
	m_pkMaterial = pkMaterial;
}
//---------------------------------------------------------------------------
const BVH* Mesh::GetBVH()
{
	return m_pkBoundingVolume;
}
//---------------------------------------------------------------------------
void Mesh::TransFormByMatrix(D3DXMATRIX * pkD3DXMatrix)
{
	Entity3D::TransFormByMatrix(pkD3DXMatrix);
	m_pkBoundingVolume->TransFormByMatrix(&m_kMatLocalTransform);
}
//---------------------------------------------------------------------------